[HVM/vncserver] Implement a 'vnclisten' option to limit the interface
authorChristian Limpach <Christian.Limpach@xensource.com>
Thu, 5 Oct 2006 13:53:29 +0000 (14:53 +0100)
committerChristian Limpach <Christian.Limpach@xensource.com>
Thu, 5 Oct 2006 13:53:29 +0000 (14:53 +0100)
that the VNC server from qemu listens on.

Defaults to only listen on 127.0.0.1

The old behaviour (listen on all interfaces) can be restored, by
- changing the system-wide default in /etc/xen/xend-config.sxp by adding:
(vnc-listen '0.0.0.0')
- changing individual domain config files by adding:
vnclisten="0.0.0.0"

Also allows specifying the hostname associated with an interface to limit
to that interface.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
tools/examples/xend-config.sxp
tools/examples/xmexample.hvm
tools/ioemu/vl.c
tools/ioemu/vl.h
tools/ioemu/vnc.c
tools/python/xen/xend/XendRoot.py
tools/python/xen/xend/image.py
tools/python/xen/xm/create.py

index 9dacf7d3c675011e4bcc8ec8b073826d1ea9d61c..ec88a9fb0912c33694376ca9e4d8f8b665531790 100644 (file)
 
 # The tool used for initiating virtual TPM migration
 #(external-migration-tool '')
+
+# The interface for VNC servers to listen on. Defaults
+# to 127.0.0.1  To restore old 'listen everywhere' behaviour
+# set this to 0.0.0.0
+#(vnc-listen '127.0.0.1')
index 731500225fa167e84ef58c1ea191bf9cc24c1cf3..cc683d42c26ecdfeee9e7a443bceb46683c20297 100644 (file)
@@ -131,6 +131,11 @@ sdl=0
 # enable VNC library for graphics, default = 1
 vnc=1
 
+#----------------------------------------------------------------------------
+# address that should be listened on for the VNC server if vnc is set.
+# default is to use 'vnc-listen' setting from /etc/xen/xend-config.sxp
+#vnclisten="127.0.0.1"
+
 #----------------------------------------------------------------------------
 # set VNC display number, default = domid
 #vncdisplay=1
index 35a9b63eaebe2f2f2d182c0a39bd89c9496b0602..7cbb8162e3e21fef2d07e2ed3d0c0d2c4e6a3d66 100644 (file)
@@ -122,6 +122,7 @@ static DisplayState display_state;
 int nographic;
 int vncviewer;
 int vncunused;
+struct sockaddr_in vnclisten_addr;
 const char* keyboard_layout = NULL;
 int64_t ticks_per_sec;
 char *boot_device = NULL;
@@ -2783,10 +2784,22 @@ fail:
     return -1;
 }
 
+int parse_host(struct sockaddr_in *saddr, const char *buf)
+{
+    struct hostent *he;
+
+    if ((he = gethostbyname(buf)) != NULL) {
+        saddr->sin_addr = *(struct in_addr *)he->h_addr;
+    } else {
+        if (!inet_aton(buf, &saddr->sin_addr))
+            return -1;
+    }
+    return 0;
+}
+
 int parse_host_port(struct sockaddr_in *saddr, const char *str)
 {
     char buf[512];
-    struct hostent *he;
     const char *p, *r;
     int port;
 
@@ -2797,14 +2810,8 @@ int parse_host_port(struct sockaddr_in *saddr, const char *str)
     if (buf[0] == '\0') {
         saddr->sin_addr.s_addr = 0;
     } else {
-        if (isdigit(buf[0])) {
-            if (!inet_aton(buf, &saddr->sin_addr))
-                return -1;
-        } else {
-            if ((he = gethostbyname(buf)) == NULL)
-                return - 1;
-            saddr->sin_addr = *(struct in_addr *)he->h_addr;
-        }
+        if (parse_host(&saddr, buf) == -1)
+            return -1;
     }
     port = strtol(p, (char **)&r, 0);
     if (r == p)
@@ -5352,6 +5359,7 @@ void help(void)
           "-vnc display    start a VNC server on display\n"
            "-vncviewer      start a vncviewer process for this domain\n"
            "-vncunused      bind the VNC server to an unused port\n"
+           "-vnclisten      bind the VNC server to this address\n"
            "-timeoffset     time offset (in seconds) from local time\n"
            "-acpi           disable or enable ACPI of HVM domain \n"
            "\n"
@@ -5444,6 +5452,7 @@ enum {
     QEMU_OPTION_acpi,
     QEMU_OPTION_vncviewer,
     QEMU_OPTION_vncunused,
+    QEMU_OPTION_vnclisten,
 };
 
 typedef struct QEMUOption {
@@ -5522,6 +5531,7 @@ const QEMUOption qemu_options[] = {
     { "vnc", HAS_ARG, QEMU_OPTION_vnc },
     { "vncviewer", 0, QEMU_OPTION_vncviewer },
     { "vncunused", 0, QEMU_OPTION_vncunused },
+    { "vnclisten", HAS_ARG, QEMU_OPTION_vnclisten },
     
     /* temporary options */
     { "usb", 0, QEMU_OPTION_usb },
@@ -5928,6 +5938,8 @@ int main(int argc, char **argv)
 
     nb_nics = 0;
     /* default mac address of the first network interface */
+
+    memset(&vnclisten_addr.sin_addr, 0, sizeof(vnclisten_addr.sin_addr));
     
     /* init debug */
     sprintf(qemu_dm_logfilename, "/var/log/xen/qemu-dm.%d.log", getpid());
@@ -6312,6 +6324,9 @@ int main(int argc, char **argv)
                 if (vnc_display == -1)
                     vnc_display = 0;
                 break;
+            case QEMU_OPTION_vnclisten:
+                parse_host(&vnclisten_addr, optarg);
+                break;
             }
         }
     }
@@ -6548,7 +6563,7 @@ int main(int argc, char **argv)
     if (nographic) {
         dumb_display_init(ds);
     } else if (vnc_display != -1) {
-       vnc_display = vnc_display_init(ds, vnc_display, vncunused);
+       vnc_display = vnc_display_init(ds, vnc_display, vncunused, &vnclisten_addr);
        if (vncviewer)
            vnc_start_viewer(vnc_display);
        xenstore_write_vncport(vnc_display);
index d44b2e334196b75dd92da03654be76986c90c84b..2cf874c054198bb00ca5baac0c304855d4b7b534 100644 (file)
@@ -37,6 +37,8 @@
 #include <unistd.h>
 #include <fcntl.h>
 #include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/types.h>
 #include "xenctrl.h"
 #include "xs.h"
 #include <xen/hvm/e820.h>
@@ -786,7 +788,7 @@ void sdl_display_init(DisplayState *ds, int full_screen);
 void cocoa_display_init(DisplayState *ds, int full_screen);
 
 /* vnc.c */
-int vnc_display_init(DisplayState *ds, int display, int find_unused);
+int vnc_display_init(DisplayState *ds, int display, int find_unused, struct sockaddr_in *addr);
 int vnc_start_viewer(int port);
 
 /* ide.c */
index 0fd6297916db6c61c8ce7419f67c6210fb3367ff..60d0449272bc0fff22a7b189ba07f71d898751d2 100644 (file)
@@ -1250,9 +1250,8 @@ static void vnc_listen_read(void *opaque)
     }
 }
 
-int vnc_display_init(DisplayState *ds, int display, int find_unused)
+int vnc_display_init(DisplayState *ds, int display, int find_unused, struct sockaddr_in *addr)
 {
-    struct sockaddr_in addr;
     int reuse_addr, ret;
     VncState *vs;
 
@@ -1290,11 +1289,10 @@ int vnc_display_init(DisplayState *ds, int display, int find_unused)
     }
 
  retry:
-    addr.sin_family = AF_INET;
-    addr.sin_port = htons(5900 + display);
-    memset(&addr.sin_addr, 0, sizeof(addr.sin_addr));
+    addr->sin_family = AF_INET;
+    addr->sin_port = htons(5900 + display);
 
-    if (bind(vs->lsock, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
+    if (bind(vs->lsock, (struct sockaddr *)addr, sizeof(struct sockaddr_in)) == -1) {
        if (find_unused && errno == EADDRINUSE) {
            display++;
            goto retry;
index 6e87dc6274c66d980e7ad76c940e560772a0c55f..4b81705b24b3d14c9668e13594277ebc708b5ead 100644 (file)
@@ -96,6 +96,9 @@ class XendRoot:
 
     dom0_vcpus_default = '0'
 
+    """Default interface to listen for VNC connections on"""
+    xend_vnc_listen_default = '127.0.0.1'
+
     components = {}
 
     def __init__(self):
@@ -272,6 +275,9 @@ class XendRoot:
     def get_console_limit(self):
         return self.get_config_int('console-limit', 1024)
 
+    def get_vnclisten_address(self):
+        return self.get_config_value('vnc-listen', self.xend_vnc_listen_default)
+
 def instance():
     """Get an instance of XendRoot.
     Use this instead of the constructor.
index 39f76c33aea7ccebe02f8bc378da8e8301ed908c..28a8952eec69e2d4ed0e5cc7c05b66234a818a4f 100644 (file)
@@ -361,6 +361,11 @@ class HVMImageHandler(ImageHandler):
             else:
                 ret += ['-vnc', '%d' % vncdisplay]
             ret += ['-k', 'en-us']
+            vnclisten = sxp.child_value(config, 'vnclisten')
+            if not(vnclisten):
+                vnclisten = xen.xend.XendRoot.instance().get_vnclisten_address()
+            if vnclisten:
+                ret += ['-vnclisten', vnclisten]
         return ret
 
     def createDeviceModel(self):
index a6374de7de91d779b5a0efe1249cf742329b4a1a..677284009615a8e37f961d6b9861c98269b1cf7d 100644 (file)
@@ -415,6 +415,10 @@ gopts.var('vncdisplay', val='',
           fn=set_value, default=None,
           use="""VNC display to use""")
 
+gopts.var('vnclisten', val='',
+          fn=set_value, default=None,
+          use="""Address for VNC server to listen on.""")
+
 gopts.var('vncunused', val='',
           fn=set_bool, default=1,
           use="""Try to find an unused port for the VNC server.
@@ -633,8 +637,9 @@ def configure_hvm(config_image, vals):
     """
     args = [ 'device_model', 'pae', 'vcpus', 'boot', 'fda', 'fdb',
              'localtime', 'serial', 'stdvga', 'isa', 'nographic', 'soundhw',
-             'vnc', 'vncdisplay', 'vncunused', 'vncconsole', 'sdl', 'display',
-             'acpi', 'apic', 'xauthority', 'usb', 'usbdevice' ]
+             'vnc', 'vncdisplay', 'vncunused', 'vncconsole', 'vnclisten',
+             'sdl', 'display', 'xauthority',
+             'acpi', 'apic', 'usb', 'usbdevice' ]
     for a in args:
         if (vals.__dict__[a]):
             config_image.append([a, vals.__dict__[a]])